﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;
using Weazel.Badger.Vhdl.Expressions;

#endregion

namespace Weazel.Badger.Vhdl.Statements
{
  public class WriteProcedure : ProcedureCallStatement
  {
    public enum NumberFormat
    {
      Binary,
      Hexadecimal,
      Decimal,
      DecimalSigned,
      DecimalUnsigned
    };

    public enum InputFormat
    {
      String,
      Identifier,
      Signal
    }

		/// <summary>
		/// Name of the buffer to write to
		/// </summary>
    private string buffer;

		/// <summary>
		/// Value to write to buffer.
		/// </summary>
    private string value;
    private Signal signal;
    private NumberFormat format;
    private InputFormat inputFormat;

    public WriteProcedure(string buffer, InputFormat inputFormat, string value)
    {      
      this.buffer = buffer;
      this.value = value;
      this.inputFormat = inputFormat;
    }

    public WriteProcedure(string buffer, Signal signal, NumberFormat format)
    {
      this.buffer = buffer;
      this.signal = signal;
      this.format = format;
      this.inputFormat = InputFormat.Signal;
    }

    public override void Write(System.CodeDom.Compiler.IndentedTextWriter writer)
    {
      switch (inputFormat)
      {
        case InputFormat.String:
          writer.WriteLine("write({0},string'(\"{1}\"));", buffer, value);
          break;

        case InputFormat.Identifier:
          writer.WriteLine("write({0},{1});", buffer, value);
          break;

        case InputFormat.Signal:

          if (signal.Type == Types.Types.StdLogic)
          {
            writer.WriteLine("write_logic({0},{1});", buffer, signal.Name);
            break;
          }

          switch (format)
          {
            case NumberFormat.Binary:
              writer.WriteLine("write({0},to_bitvector({1}));", buffer, signal.Name);
              break;
            case NumberFormat.DecimalSigned:
              writer.WriteLine("write_dec_signed({0},{1});", buffer, signal.Name);
              break;
            case NumberFormat.DecimalUnsigned:
              writer.WriteLine("write_dec_unsigned({0},{1});", buffer, signal.Name);
              break;
            case NumberFormat.Hexadecimal:
              writer.WriteLine("write_hex({0},{1});", buffer, signal.Name);
              break;
            case NumberFormat.Decimal:              
              writer.WriteLine("write_dec_unsigned({0},{1});", buffer, signal.Name);
              break;
              
						// unknown format
            default:
              throw new NotSupportedException("Unknown format");
          }
          break;

        default:
          throw new NotSupportedException("Unknown input format");
      }
    }
  }
}
